#comment：用于zabbix监控windows服务器的磁盘用量，CPU用量，内存用量，内外网卡流量，每秒中断数性能信息
#function： 于powershell环境中运行，被统计的windows服务器的需要开启WMI服务:sc start winmgmt,默认端口为 135
#        . /check_windows.ps1 
#        . /check_windows.ps1 C:,D:,E:,CPU,MEM,Public_Send,Public_Receive,Private_Send,Private_Receive,InterRupts
#author sixther.me
#date   2014-08-13

#定义数组，用来保存每台服务器的性能信息类
$objects = @()
#对于网卡流量，中断数，需要统计两次，做平均运算，定义两个数组，保存两次统计的服务器性能信息类
$first_datas = @()
$second_datas = @()
#外网网卡名
$public_interface = "Broadcom BCM5716C NetXtreme II GigE [NDIS VBD Client] _20"
#内网网卡名
$private_interface = "Broadcom BCM5716C NetXtreme II GigE [NDIS VBD Client] _30"
$Processor_Name = "_Total"
#定义获取分区使用量函数，用到的WMI类为:Win32_LogicalDisk,从该类获取需要的数去存入i_object类
function get_logicdisk_info()
{
    $Logic_Disk = @()
    $query = "select * from Win32_LogicalDisk where DriveType = 3"
    $Logic_Disk = Get-WmiObject -query $query
    foreach ($i in $Logic_Disk)
    {
        $Used_Percent = ($i.Size - $i.FreeSpace) / $i.Size * 100
        $Used_Percent = ( "{0:N2}" -f $Used_Percent)     #保留两位小数
#添加磁盘用量属性
        $i_object | Add-Member -MemberType NoteProperty -name ($i.DeviceID) -value $Used_Percent


    }
}
#定义CPU使用量函数,用到的WMI类为:Win32_PerfFormattedData_PerfOS_Processor
function get_cpu_used_info()
{
	$n=0
    $cpu_used = @()
    $query = "select * from  Win32_PerfFormattedData_PerfOS_Processor where name != '$Processor_Name'"
    $cpu_used = Get-WmiObject -query $query
    $cpu_used | ForEach-Object {
        $n++
        $idle_sum = $idle_sum + $_.PercentIdleTime
    }
#添加CPU使用量属性
    $i_object | Add-Member -MemberType NoteProperty -name "CPU" -value ( "{0:N2}" -f ( 100 - ($idle_sum / $n)))
    
}
#定义内存使用量函数，用到的WMI类为：win32_logicalmemoryconfiguration，win32_perfrawdata_perfos_memory
function get_mem_info()
{
    $query = "select * from win32_logicalmemoryconfiguration"
    $memory = Get-WmiObject -query $query
    $total_memory = $memory.TotalPhysicalMemory
    $query = "select * from win32_perfrawdata_perfos_memory"
    $memory = Get-WmiObject -query $query
    $avail_memory = $memory.AvailableKBytes
    $used_memory = $total_memory - $avail_memory
    $used_percent = $used_memory / $total_memory * 100
#添加内存使用量属性
    $i_object | Add-Member -MemberType NoteProperty -name "MEM" -value ( "{0:N2}" -f $Used_Percent)
}
#定义获取网卡流量函数，用到的WMI类为：Win32_PerfRawData_Tcpip_NetworkInterface
function get_tcpip_info($self,$interface_name,$send_member,$receiev_member)
{
    $query = "select * from Win32_PerfRawData_Tcpip_NetworkInterface where name = '$interface_name'"
    $tcpip_data = Get-WmiObject -query $query
    $self | Add-Member -MemberType NoteProperty -name $send_member -value $tcpip_data.BytesSentPersec
    $self | Add-Member -MemberType NoteProperty -name $receiev_member -value $tcpip_data.BytesReceivedPersec
    
}
#定义获取中断数函数，用到的WMI类为:Win32_PerfRawData_PerfOS_Processor
function get_interrupt_info($self,$interrupt_member,$time_stamp,$frequency)
{
    $query = "select * from Win32_PerfRawData_PerfOS_Processor where name = '$Processor_Name'"
    $interrupt_data = Get-WmiObject -query $query
    $self | Add-Member -MemberType NoteProperty -name $interrupt_member -value $interrupt_data.InterruptsPersec
    $self | Add-Member -MemberType NoteProperty -name $time_stamp -value $interrupt_data.Timestamp_PerfTime
    $self | Add-Member -MemberType NoteProperty -name $frequency -value $interrupt_data.Frequency_PerfTime
}


#获取服务器第一次统计的网卡流量，中断数信息，存入$first_datas类数组
$first_data = New-Object system.object
get_tcpip_info $first_data $public_interface "Public_Send" "Public_Receive"
get_tcpip_info $first_data $private_interface "Private_Send" "Private_Receive"
get_interrupt_info $first_data "InterRupts" "Times_Stamp" "Frequency"
sleep 3
# 10 秒后获取服务器第二次统计的网卡流量，中断数信息，存入$second_datas类数组
$second_data = New-Object system.object
get_tcpip_info $second_data $public_interface "Public_Send" "Public_Receive"
get_tcpip_info $second_data $private_interface "Private_Send" "Private_Receive"
get_interrupt_info $second_data "InterRupts" "Times_Stamp" "Frequency"


#主函数，调用函数，获取服务器信息，最终得到所有服务器的性能数据，存入$objects类数组
    $seconds = 3
    $i_object = New-Object system.object
    get_logicdisk_info
    get_mem_info
    get_cpu_used_info
#从前后两次获取的数据类数组中提取数据，运算得到最终数据存入$i_object类
    $first_data_obj = $first_data
    $second_data_obj = $second_data
    $seconds = (($second_data_obj.Times_Stamp - $first_data_obj.Times_Stamp) / $first_data_obj.Frequency)
    ( "Public_Send" , "Public_Receive" , "Private_Send" , "Private_Receive" , "InterRupts" ) | ForEach-Object {
        $base = $seconds
        $i_object | Add-Member -MemberType NoteProperty -name $_ -value ( "{0:N2}" -f (([double]$second_data_obj.$_ - [double]$first_data_obj.$_) / $base))
    }
    
$member=$args[0]
$i_object.$member
#$check_value.$args[0]
#$check_value=$i_object.$args[0]
#echo $check_value
#i_object类结构：


#Name            MemberType   Definition
# - - - -              - - - - - - - - - -     - - - - - - - - - -
#Equals          Method       bool Equals(System. Object obj)
#GetHashCode     Method       int GetHashCode()
#GetType          Method       type GetType ()
#ToString        Method        string ToString()
#C:              NoteProperty System. String C:= 8 . 68
#CPU             NoteProperty System. String CPU= 1 .00
#D:              NoteProperty System. String D:= 4 . 32
#E:              NoteProperty System. String E:= 13 . 90
#InterRupts      NoteProperty System. String InterRupts= 17 , 311 . 14
#MEM             NoteProperty System. String MEM= 14 . 58
#Private_Receive NoteProperty System. String Private_Receive= 99 . 43
#Private_Send    NoteProperty System. String Private_Send= 56 . 72
#Public_Receive  NoteProperty System. String Public_Receive= 0 . 59
#Public_Send     NoteProperty System. String Public_Send= 0 . 51